package com.zkthink.ceres.pay.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.google.gson.Gson;
import com.zkthink.base.R;
import com.zkthink.ceres.pay.config.WxAppConfiguration;
import com.zkthink.ceres.pay.config.WxMaConfiguration;
import com.zkthink.ceres.pay.dto.AliPayTranDTO;
import com.zkthink.ceres.pay.dto.TransfersDTO;
import com.zkthink.ceres.pay.service.PayTransferService;
import com.zkthink.ceres.pay.utils.HttpRequestHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @ClassName AliPayServiceImpl
 * @Description: 提现
 * @Author ck
 * @Date 2021/12/16
 * @Version V1.0
 **/
@Slf4j
@Service
@AllArgsConstructor
public class PayTransferImpl implements PayTransferService {

    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private WxAppConfiguration wxAppConfiguration;
    @Autowired
    private WxMaConfiguration wxMaConfiguration;

    @Override
    public R<AlipayFundTransUniTransferResponse> aliTranfer(String tradingNo, String amount, String payerShowName, String payeeAccount, String remark) {
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        AliPayTranDTO alipay = new AliPayTranDTO();
        alipay.setOut_biz_no(tradingNo);
        alipay.setPayee_type("ALIPAY_LOGONID");
        alipay.setAmount(amount);
        alipay.setPayer_show_name(payerShowName);
        alipay.setPayee_account(payeeAccount);
        alipay.setRemark(remark);
        // 转成json格式放入
        String json = new Gson().toJson(alipay);
        request.setBizContent(json);
        AlipayFundTransUniTransferResponse response = null;
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            response = alipayClient.certificateExecute(request);
            System.out.println("阿里提现回执:" + response.toString());
            if ("10000".equals(response.getCode())) {
                return R.success(response);
            } else {
                return R.fail(response.getMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return R.fail("转账失败");
        }
    }

    /**
     * @param iP               IP地址
     * @param money            金额 元
     * @param openID           支付给用户openid
     * @param mch_name         商户姓名
     * @param desc             企业付款操作说明信息。必填
     * @param partner_trade_no 生成商户订单号
     * @return
     */
    @Override
    public R wxTranfer(String iP, String money, String openID, String mch_name, String desc, String partner_trade_no) {
        TransfersDTO model = new TransfersDTO();
        model.setMch_appid(wxMaConfiguration.getAppid());
        model.setMchid(wxAppConfiguration.getAppid());
        model.setAmount(money);
        model.setOpenid(openID);
        model.setPartner_trade_no(partner_trade_no);
        model.setDesc(desc);
        model.setSpbill_create_ip(iP);
        model.setMch_name(mch_name);
        model.setAppkey(wxAppConfiguration.getAppKey());
        try {
            // 1.计算参数签名
            String paramStr = createLinkString(model);
            String mysign = paramStr + "&key=" + model.getAppkey();
            String sign = DigestUtils.md5Hex(mysign).toUpperCase();

            // 2.封装请求参数
            StringBuilder reqXmlStr = new StringBuilder();
            reqXmlStr.append("<xml>");
            reqXmlStr.append("<mchid>" + model.getMchid() + "</mchid>");
            reqXmlStr.append("<mch_appid>" + model.getMch_appid() + "</mch_appid>");
            reqXmlStr.append("<nonce_str>" + model.getNonce_str() + "</nonce_str>");
            reqXmlStr.append("<check_name>" + model.getCheck_name() + "</check_name>");
            reqXmlStr.append("<openid>" + model.getOpenid() + "</openid>");
            reqXmlStr.append("<amount>" + model.getAmount() + "</amount>");
            reqXmlStr.append("<desc>" + model.getDesc() + "</desc>");
            reqXmlStr.append("<sign>" + sign + "</sign>");
            reqXmlStr.append("<partner_trade_no>" + model.getPartner_trade_no() + "</partner_trade_no>");
            reqXmlStr.append("<spbill_create_ip>" + model.getSpbill_create_ip() + "</spbill_create_ip>");
            reqXmlStr.append("</xml>");

            // 3.加载证书请求接口
            String result = HttpRequestHandler.httpsRequest(wxAppConfiguration.getTransUrl(), reqXmlStr.toString(),
                    model, wxAppConfiguration.getCertPath());
            System.out.println("response xml = " + result);
            if (result.contains("CDATA[FAIL]")) {
                return R.fail("调用微信接口失败, 具体信息请查看访问日志");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());

        }
        return R.success();
    }

    private String createLinkString(TransfersDTO model) {
        Map<String, Object> paramMap = new HashMap<String, Object>();

        // 订单号默认用商户号+时间戳+4位随机数+可以根据自己的规则进行调整
        model.setAppkey(wxAppConfiguration.getAppKey());
        model.setNonce_str(getNonce_str());
//        model.setPartner_trade_no(model.getMchid()
//                + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
//                + (int)((Math.random() * 9 + 1) * 1000));
        paramMap.put("mch_appid", model.getMch_appid());
        paramMap.put("mchid", model.getMchid());
        paramMap.put("openid", model.getOpenid());
        paramMap.put("amount", model.getAmount());
        paramMap.put("check_name", model.getCheck_name());
        paramMap.put("desc", model.getDesc());
        paramMap.put("partner_trade_no", model.getPartner_trade_no());
        paramMap.put("nonce_str", model.getNonce_str());
        paramMap.put("spbill_create_ip", model.getSpbill_create_ip());

        List<String> keys = new ArrayList(paramMap.keySet());
        Collections.sort(keys);
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            Object value = (Object) paramMap.get(key);
            if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }
        return prestr;
    }

    private String getNonce_str() {
        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 15; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

}
